import datetime
import os
import time
import traceback
import json

import requests
from loguru import logger
import hashlib


class Wei_Dian:
    def __init__(self, playwright, host, app_id):
        self.app_id = app_id
        self.secret = "P4I8HCOP1OP7432XZVKR2MPJKKVQ7J"
        self.playwright = playwright
        self.host = host
        self.context = None
        self.browser = None
        self.page = None
        self.index_url = "https://d.weidian.com/weidian-pc/login/#/"
        self.fund_flow_download_path = os.path.join(os.getcwd(), 'wdFundFlow')
        if not os.path.exists(self.fund_flow_download_path):
            os.makedirs(self.fund_flow_download_path)

    def login(self, store):
        browser = self.playwright.chromium.launch(headless=False)
        self.context = browser.new_context(accept_downloads=True)
        self.page = self.context.new_page()
        self.page.goto(self.index_url, timeout=20000)
        self.page.query_selector('input[name="telephone"]').fill(store['userName'])
        self.page.query_selector('input[name="login-pwd"]').fill(store['pwd'])
        time.sleep(1)
        self.page.query_selector('label[role="checkbox"]').click()
        logger.info('点击登录...')
        self.page.query_selector('button.weidian-button').click()
        self.wait_for_loading('div.shop-select')
        logger.info('登录成功')
        # 选择店铺，按照店铺标识选择
        if self.page.query_selector(f'div[title="{store["account"]}"]') is None:
            logger.info(f'按照店铺标识【{store["account"]}】找不到店铺')
            return
        self.page.query_selector(f'div[title="{store["account"]}"]').click()
        self.wait_for_loading('a[data-spider-action-name="资产"]')

    def wait_for_loading(self, path):
        for i in range(20):
            try:
                if self.page.query_selector(path) is not None and self.page.query_selector(path).is_visible():
                    break
            except:
                pass
            time.sleep(1)
            logger.info(f'等待页面加载【{i+1}】秒...')

    def download_fund_flow(self, store, yesterday):
        logger.info('点击资产...')
        self.page.query_selector('a[data-spider-action-name="资产"]').click()
        self.wait_for_loading('input[placeholder="开始日期"]')
        self.page.query_selector('input[placeholder="开始日期"]').fill(yesterday)
        time.sleep(1)
        self.page.query_selector('input[placeholder="结束日期"]').fill(yesterday)
        with self.page.expect_response('https://thor.weidian.com/itemappser/withdrawal.branchShopStatementList/*') as res:
            self.page.query_selector('button[data-spider-action-name="筛选"]').click()
        response = res.value
        self.wait(self.page)
        if response.status:
            total = response.json()['result']['total']
            if total == 0:
                logger.info('暂无数据')
                return None
            logger.info('点击导出报表...')
            self.page.query_selector('button[data-spider-action-name="导出报表"]').click()
            self.wait_for_loading('button[data-spider-action-name="生成报表"]')
            logger.info('点击生成报表...')
            self.page.query_selector('button[data-spider-action-name="生成报表"]').click()
            self.wait_for_loading('div.wrap-export')
            record = self.page.query_selector('div.wrap-export >> div.record-item >> nth=0')
            export_info = record.query_selector('div.item-bd').text_content()
            logger.info(f'导出信息：{export_info}')
            # 判断报表是否生成完成
            download_btn = record.query_selector('button[data-spider-action-name="下载报表"]')
            for i in range(60):
                if download_btn is None:
                    logger.info('等待报表生成')
                    time.sleep(10)
                    # 刷新页面
                    self.page.reload()
                    self.wait_for_loading('div.wrap-export')
                    record = self.page.query_selector('div.wrap-export >> div.record-item >> nth=0')
                    download_btn = record.query_selector('button[data-spider-action-name="下载报表"]')
                else:
                    break
            if download_btn is None:
                logger.info('下载文件超时')
                raise Exception('下载文件超时')
            # 下载报表
            with self.page.expect_download() as download_info:
                self.page.query_selector('button[data-spider-action-name="下载报表"]').click()
            download_obj = download_info.value
            file_path = os.path.join(self.fund_flow_download_path, f'wdFundFlow-{store["platformStoreName"]}-{yesterday}-{datetime.datetime.now().strftime("%Y%m%d%H%M%S")}.xlsx')
            # 删除旧文件
            if os.path.exists(file_path):
                os.remove(file_path)
            download_obj.save_as(file_path)
            # 等待文件下载完成
            for i in range(60):
                if os.path.exists(file_path):
                    break
                time.sleep(1)
            if not os.path.exists(file_path):
                raise Exception(f"【{file_path}】下载失败")
            logger.info(f"【{file_path}】下载成功")
            return file_path
        else:
            raise Exception('查询超时')

    def get_fund_flow_count(self, period):
        logger.info('点击资产...')
        self.page.query_selector('a[data-spider-action-name="资产"]').click()
        self.wait_for_loading('input[placeholder="开始日期"]')
        start_date = period + '-01'
        self.page.query_selector('input[placeholder="开始日期"]').fill(start_date)
        time.sleep(1)
        end_date = ((datetime.datetime.strptime(start_date, '%Y-%m-%d') + datetime.timedelta(days=31)).replace(day=1) - datetime.timedelta(days=1)).strftime('%Y-%m-%d')
        self.page.query_selector('input[placeholder="结束日期"]').fill(end_date)
        with self.page.expect_response('https://thor.weidian.com/itemappser/withdrawal.branchShopStatementList/*') as res:
            self.page.query_selector('button[data-spider-action-name="筛选"]').click()
        response = res.value
        self.wait(self.page)
        if response.status:
            total = response.json()['result']['total']
            return total
        else:
            raise Exception('查询失败')

    def get_store_account(self, platform, type):
        timestamp = int(time.time() * 1000)
        text = "{}{}{}".format(self.app_id, timestamp, self.secret)
        sign = hashlib.md5(text.encode(encoding='UTF-8')).hexdigest()
        url = self.host + f"api/v1/storeAccount/getAccountList/{platform}?appId={self.app_id}&type={type}&sign={sign.upper()}&timestamp={timestamp}"
        logger.info(url)
        res = requests.get(url)
        logger.info(f'获取店铺账号结果：{res.text}')
        if res.status_code == 200:
            return res.json()['data']

    # 获取图鉴账号密码
    def get_tujian_account(self):
        timestamp = int(time.time() * 1000)
        text = "{}{}{}".format(self.app_id, timestamp, self.secret)
        sign = hashlib.md5(text.encode(encoding='UTF-8')).hexdigest()
        url = self.host + f"api/v1/tjAccount/findOne?appId={self.app_id}&sign={sign.upper()}&timestamp={timestamp}"
        res = requests.get(url)
        if res.status_code == 200:
            return res.json()['data']

    # 获取任务ID
    def get_job_id(self, key):
        timestamp = int(time.time() * 1000)
        text = "{}{}{}".format(self.app_id, timestamp, self.secret)
        sign = hashlib.md5(text.encode(encoding='UTF-8')).hexdigest()
        url = self.host + f"api/v1/storeAccount/getJobId/{key}?appId={self.app_id}&sign={sign.upper()}&timestamp={timestamp}"
        res = requests.get(url)
        if res.status_code == 200:
            return res.json()['data']

    # 更新流程日志状态
    def save_log_record(self, data):
        timestamp = int(time.time() * 1000)
        text = "{}{}{}".format(self.app_id, timestamp, self.secret)
        sign = hashlib.md5(text.encode(encoding='UTF-8')).hexdigest()
        url = self.host + f"api/v1/logRecord/saveLog?appId={self.app_id}&sign={sign.upper()}&timestamp={timestamp}"
        logger.info(f'保存日志参数：{data}')
        res = requests.post(url, json=data)
        logger.info(f'保存日志结果：{res.text}')
        if res.status_code == 200:
            return res.json()['data']

    def wait(self, page, seconds=1):
        try:
            page.wait_for_load_state(state="domcontentloaded")
            time.sleep(seconds)
        except:
            pass

    def close(self):
        try:
            if self.page:
                self.page.close()
        except:
            pass
        try:
            if self.browser:
                self.browser.close()
        except:
            pass
        try:
            if self.context:
                self.context.close()
        except:
            pass

    def upload_file(self, api_url, coding_param, file_list):
        try:
            timestamp = int(time.time() * 1000)
            text = "{}{}{}".format(self.app_id, timestamp, self.secret)
            sign = hashlib.md5(text.encode(encoding='UTF-8')).hexdigest()
            logger.info("正在上传文件到服务器")
            url = self.host + api_url + f"?appId={self.app_id}&sign={sign.upper()}&timestamp={timestamp}"
            files = []
            for file in file_list:
                files.append(('file', (open(file, 'rb'))))
            logger.info(f'上传文件到服务器url：{url}')
            response = requests.request("POST", url, files=files, headers={'codingParam': coding_param}, timeout=180)
            logger.info('上传文件到服务器结果：' + response.text)
        except:
            logger.info(traceback.format_exc())

    def encode_param(self, data_list):
        timestamp = int(time.time() * 1000)
        text = "{}{}{}".format(self.app_id, timestamp, self.secret)
        sign = hashlib.md5(text.encode(encoding='UTF-8')).hexdigest()
        url = self.host + f"api/v1/storeAccount/codingParams?appId={self.app_id}&sign={sign.upper()}&timestamp={timestamp}"
        res = requests.post(url, data=json.dumps(data_list), headers={'content-type': 'application/json'})
        if res.status_code == 200:
            return res.json()['data']